<?php

abstract class FP_Model_Gateway implements FP_Model_Gateway_Interface
{
    protected $_dao_class = null;
    protected $_model_class = null;
    protected $_model_collection_class = 'FP_Model_Collection';

    protected $_primary_key = 'id';

    public function fetch($pCriteria=null, $pOffset=null, $pLimit=null, $pOrderBy=null){
	return array();
    }

    public function count($pCriteria=null){
	return 0;
    }

    public function preSave(array $pData){
	return $pData;
    }

    public function postSave(array $pData){
	return $pData;
    }

    public function save(array $pData){
	throw new FP_Exception('Feature not implemented', FP_Exception::NOT_IMPLEMENTED);
    }

    public function preDelete($pModel){
	return $pModel;
    }

    public function postDelete($pModel){
	return $pModel;
    }

    public function delete($pModel){
	throw new FP_Exception('Feature not implemented', FP_Exception::NOT_IMPLEMENTED);
    }

    public function create(array $pData=array(), $pAutoSave=false, $pAutoSaveValidate=true){
	throw new FP_Exception('Feature not implemented', FP_Exception::NOT_IMPLEMENTED);
    }

    public function getPaginator($pCriteria, $pOrderBy=null){
    //       logdebug("Fetching paginator with criteria " . logobject($pCriteria));
	return new Zend_Paginator(new FP_Model_Paginator_Adapter($pCriteria, $this, $pOrderBy));
    }

    public function getModelObjectId($pObject){
	if (is_numeric($pObject))
	    return $pObject;
	else if (get_class($pObject) == $this->_model_class)
	    return $pObject->{$this->_primary_key};
	else
	    return null;
	    //throw new Exception("Must specify a valid {$this->_model_class}");
    }

    public function getModelObject($pObject){
	if (is_numeric($pObject))
	    return $this->fetch($pObject);
	else if (get_class($pObject) == $this->_model_class)
	    return $pObject;
	else
	    return new $this->_model_class(array(), $this);
// 	    throw new Exception("Must specify a valid {$this->_model_class}");
    }

    //Accepts collection of doctrine rows and converts them to model collection
    public function getModelCollection($pCollection){
    	if (is_array($pCollection))
	    return new $this->_model_collection_class($pCollection, $this, $this->_model_class);
    	else if ($pCollection instanceof FP_Model_Collection)
	    return new $this->_model_collection_class($pCollection->toArray(), $this, $this->_model_class);
    }

    public function resolveRoute($pRouteName, array $pParams=array()){
	$route = Zend_Controller_Front::getInstance()->getRouter()->getRoute($pRouteName);
	return $route->assemble($pParams);
    }

    public function __call($pMethod, $pArgs){

	if (preg_match('/^fetchBy(.*)$/', $pMethod, $matches)){

	    $field = strtolower(from_camel_case($matches[1]));
	    $results = $this->fetch(array($field => $pArgs[0]));

	    if (count($pArgs) == 2 && $pArgs[1] === true){ //if second argument is true, fetch single record

		if (count($results) > 0)
		    return $results->current();
		return null;

	    } else
		return $results;

	} else
	    throw new Exception("No such method - " . $pMethod);

    }
}

?>